/*
 * Copyright 2011 OpenWAF.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.openwaf.client.ui.widget;

import com.openwaf.client.dom.DivElement;
import com.openwaf.client.dom.OListElement;
import com.openwaf.client.ui.ElementNotFoundException;
import com.openwaf.client.ui.UIControl;
import com.openwaf.client.ui.annotation.ViewMethod;
import com.openwaf.client.ui.annotation.ViewProperty;
import java.util.ArrayList;
import java.util.Iterator;

public class TreeView extends UIControl implements Iterable<TreeNode> {

    public static String CSS_TREE = "waf-widget-treeview";
    public static String CSS_CHILD_BLOCK = "waf-widget-treenode-block";
    public static String CSS_NODE = "waf-widget-treenode";
    public static String CSS_NODE_STATE_LEAF = "waf-widget-treenode-state-leaf";
    public static String CSS_NODE_STATE_COLLAPSED = "waf-widget-treenode-state-collapsed";
    public static String CSS_NODE_STATE_EXPANDED = "waf-widget-treenode-state-expanded";
    public static String CSS_TEXT = "waf-widget-treenode-text";
    private String css_tree = CSS_TREE;
    private String css_child_block = CSS_CHILD_BLOCK;
    private String css_node = CSS_NODE;
    private String css_node_state_leaf = CSS_NODE_STATE_LEAF;
    private String css_node_state_collapsed = CSS_NODE_STATE_COLLAPSED;
    private String css_node_state_expanded = CSS_NODE_STATE_EXPANDED;
    private String css_text = CSS_TEXT;

    @ViewProperty
    public void setCssTree(String name) {        
        css_tree = name;
        getElement().setCssClassName(name);
    }

    public String getCssTree() {
        return css_tree;
    }

    @ViewProperty
    public void setCssChildBlock(String name) {
        custumized = true;
        css_child_block = name;
        updateCss();
    }

    public String getCssChildBlock() {
        return css_child_block;
    }

    @ViewProperty
    public void setCssNode(String name) {
        custumized = true;
        css_node = name;
        updateCss();
    }

    public String getCssNode() {
        return css_node;
    }

    @ViewProperty
    public void setCssNodeStateLeaf(String name) {
        custumized = true;
        css_node_state_leaf = name;
        updateCss();
    }

    public String getCssNodeStateLeaf() {
        return css_node_state_leaf;
    }

    @ViewProperty
    public void setCssNodeStateCollapsed(String name) {
        custumized = true;
        css_node_state_collapsed = name;
        updateCss();
    }

    public String getCssNodeStateCollapsed() {
        return css_node_state_collapsed;
    }

    @ViewProperty
    public void setCssNodeStateExpanded(String name) {
        custumized = true;
        css_node_state_expanded = name;
        updateCss();
    }

    public String getCssNodeStateExpanded() {
        return css_node_state_expanded;
    }

    @ViewProperty
    public void setCssText(String name) {
        custumized = true;
        css_text = name;
        updateCss();
    }

    public String getCssText() {
        return css_text;
    }

    private void updateCss(){
        if(custumized){
            olChilds.setCssClassName(css_child_block);
        }        
    }
    private boolean custumized;
    private ArrayList<TreeNode> childs;
    private OListElement olChilds;

    public TreeView() {
        childs = new ArrayList<TreeNode>();
    }

    @ViewMethod
    public void addChild(TreeNode node) {
        childs.add(node);
        olChilds.appendChild(node.getElement());
        node.setTreeView(this);
        node.updateCss();        
    }

    public void addChild(int index, TreeNode node) {
        if (index < 0 || index > childs.size()) {
            throw new IndexOutOfBoundsException("Index out of range in TreeNode::addChildAt");
        }
        TreeNode ex = childs.get(index);
        childs.add(index, node);
        olChilds.insertBefore(node.getElement(), ex.getElement());
        node.setTreeView(this);
        node.updateCss();        
    }

    public TreeNode getChild(int index) {
        if (index < 0 || index > childs.size()) {
            throw new IndexOutOfBoundsException("Index out of range in TreeNode::addChildAt");
        }
        return childs.get(index);
    }

    public void removeChild(TreeNode tn) {
        int index = childs.indexOf(tn);
        if (index < 0) {
            throw new ElementNotFoundException("Element not found in child list");
        }
        removeChild(index);
    }

    public void removeChild(int index) {
        if (index < 0 || index > childs.size()) {
            throw new IndexOutOfBoundsException("Index out of range in TreeNode::addChildAt");
        }
        TreeNode tn = childs.get(index);
        olChilds.removeChild(tn.getElement());
        tn.setTreeView(null);
    }

    public Iterator<TreeNode> iterator() {
        return childs.iterator();
    }
}
